package com.bjb.vr.remote.ws.rabbitmq.handler.impl;

import com.alibaba.fastjson.JSONObject;
import com.bjb.vr.common.constant.ThreadLocalConstant;
import com.bjb.vr.common.dto.ResDevLoginRecord;
import com.bjb.vr.common.dto.ResDevice;
import com.bjb.vr.common.dto.ResGroup;
import com.bjb.vr.common.result.BaseResult;
import com.bjb.vr.common.service.ResDevLoginRecordService;
import com.bjb.vr.common.service.ResDeviceService;
import com.bjb.vr.common.service.ResGroupService;
import com.bjb.vr.common.utils.DateTimeUtil;
import com.bjb.vr.common.utils.RedisUtil;
import com.bjb.vr.common.utils.ThreadLocalUtil;
import com.bjb.vr.remote.ws.rabbitmq.constants.MessageActionConstants;
import com.bjb.vr.remote.ws.rabbitmq.entity.RabbitWebSocketMsg;
import com.bjb.vr.remote.ws.rabbitmq.handler.MessageHandler;
import com.bjb.vr.remote.ws.redis.constants.RedisConstants;
import com.bjb.vr.remote.ws.websocket.entity.Action;
import com.bjb.vr.remote.ws.websocket.entity.Command;
import com.bjb.vr.remote.ws.websocket.vo.Message;
import com.bjb.vr.remote.ws.websocket.websocket.WebSocketMsgHandler;
import com.github.yitter.idgen.YitIdHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.Map;

/**
 * @version 1.0.0
 * @description:
 * @author: caihaibo
 * @createDate: 2022/3/29
 */
@Component
@Slf4j
public class CvrOnlineStateMessageHandler implements MessageHandler {

    @Autowired
    ResDeviceService resDeviceService;

    @Autowired
    ResGroupService resGroupService;

    @Autowired
    RedisUtil redisUtil;
    @Autowired
    ResDevLoginRecordService resDevLoginRecordService;

    final String  LOCK_KEY = "res_device_online_state";

    @Override
    public void process(RabbitWebSocketMsg rabbitWebSocketMsg)  {
        String dbLockKey = RedisConstants.WEBSOCKET_DB_OP_LOCK_KEY + LOCK_KEY + rabbitWebSocketMsg.getDeviceId();

        String connectDevKey = RedisConstants.WEBSOCKET_DEV_CONNECT_IDS + rabbitWebSocketMsg.getDeviceId();

        String startTimeKey = "startTime";

        JSONObject jsonObject = JSONObject.parseObject(rabbitWebSocketMsg.getMsg());

        Message message = JSONObject.toJavaObject(jsonObject, Message.class);

        if(message.getAction().equals(MessageActionConstants.MESSAGE_ACTION_CVR_ONLINE_STATE)) {
            log.info("处理在线离线状态上传信息");

            JSONObject _jsonObject = JSONObject.parseObject(message.getCommand().getParameter());
            String value = String.valueOf(System.currentTimeMillis());
            int onlineState = _jsonObject.getInteger("onlineState");
            try{
                if(rabbitWebSocketMsg.getIsAdmin() !=null && rabbitWebSocketMsg.getIsAdmin().equals("1")){
                    //processAdminOfflineStopClass(rabbitWebSocketMsg.getGroupCode(),onlineState,kick);
                }else {
                    WebSocketMsgHandler.sendAdmin(rabbitWebSocketMsg);
                }

                if(redisUtil.lock(dbLockKey, value, RedisConstants.WEBSOCKET_DB_OP_LOCK_KEY_EXPIRE_TIME)) {

                    if(rabbitWebSocketMsg.getIsAdmin() !=null && rabbitWebSocketMsg.getIsAdmin().equals("1")){
                        log.info("处理web端在线离线状态，收到消息 " + rabbitWebSocketMsg.getMsg() + " onlineState = " + onlineState);
                        processAdminDB(rabbitWebSocketMsg.getGroupCode(),onlineState);
                    }else{
                        log.info("处理客户端在线离线状态，收到消息 " + rabbitWebSocketMsg.getMsg() + " onlineState = " + onlineState);
                        processClient(rabbitWebSocketMsg,message,connectDevKey,startTimeKey,onlineState);
                    }
                    redisUtil.unlock(dbLockKey, value);
                }
            }catch(Exception ex){
                ex.printStackTrace();
                log.error("处理在线离线状态出错,消息 " +  rabbitWebSocketMsg ,ex);
            }

        }
    }

    private void processAdminOfflineStopClass(String groupCode,int onlineState,boolean kick){
        log.info("processAdminOfflineStopClass groupCode " + groupCode  + " onlineState " +  onlineState + " kick " + kick);
        if(onlineState ==0 && kick) {
            ResGroup resGroup = new ResGroup();
            BaseResult<ResGroup> result = resGroupService.checkGroupCode(groupCode);
            if (result.isSuccess()) {
                resGroup = result.getData();
                if (resGroup != null) {
                    long contentId = resGroup.getContentId();
                    //1:上课 2:下课 -1:初始状态
                    int classState = resGroup.getClassState();
                    if (contentId != 0 && classState == 1) {
                        Action action = new Action();
                        action.setAction(MessageActionConstants.MESSAGE_ACTION_STOP_CALSS);
                        Command command = new Command<>();
                        action.setCommand(command);
                        String msg = JSONObject.toJSONString(action);
                        RabbitWebSocketMsg rabbitWebSocketMsg = new RabbitWebSocketMsg();
                        rabbitWebSocketMsg.setIsAdmin("1");
                        rabbitWebSocketMsg.setGroupCode(groupCode);
                        rabbitWebSocketMsg.setMsg(msg);
                        WebSocketMsgHandler.sendAllClient(rabbitWebSocketMsg);

                        resGroup.setClassState(2);
                        resGroup.setSectionNo(-1);
                        resGroup.setSoundState(-1);
                        resGroup.setLockState(-1);
                        resGroup.setPlayState(-1);
                        resGroup.setCtrlModeState(-1);
                        resGroup.setTimeline(-1);
                        resGroupService.updateResGroupByGroupCode(resGroup);
                    }
                }
            }
        }
    }

    private void processAdminDB(String groupCode,int onlineState){
        resGroupService.updateResGroupAdmConStateByGroupCode(groupCode,onlineState);
    }

    private void processClient(RabbitWebSocketMsg rabbitWebSocketMsg,Message message,String connectDevKey, String startTimeKey, int onlineState){
        resDeviceService.updateResDeviceOnlinieStateByUdid(message.getCommand().getUdid(), onlineState);
        if(onlineState == 1 )//上线
        {
            redisUtil.hdel(connectDevKey, startTimeKey);
            redisUtil.hset(connectDevKey, startTimeKey, new Date(), RedisConstants.WEBSOCKET_CLIENT_CONNECT_EXPIRE_TIME);

        }else if(onlineState == 0){
            Date startTime = (Date) redisUtil.hget(connectDevKey,startTimeKey);
            Date endTime = new Date();
            LocalDateTime endLocalDateTime = DateTimeUtil.getLocalDateTime(endTime);
            LocalDateTime startLocalDateTime = DateTimeUtil.getLocalDateTime(startTime);
            long useTime =   (endTime.getTime() - startTime.getTime())/1000;
            BaseResult result =  resDeviceService.getResDeviceByUdid(rabbitWebSocketMsg.getDeviceId());
            if(result.isSuccess()) {
                ResDevice resDevice = (ResDevice) result.getData();
                ResDevLoginRecord loginRecord = new ResDevLoginRecord();
                loginRecord.setTenantId(resDevice.getTenantId());
                loginRecord.setUdid(rabbitWebSocketMsg.getDeviceId());
                loginRecord.setDevLoginTime(startLocalDateTime);
                loginRecord.setDevLoginDate(startLocalDateTime.toLocalDate());
                loginRecord.setDevLogoutTime(endLocalDateTime);
                loginRecord.setDevUseTime(Double.valueOf(useTime));
                loginRecord.setGmtCreate(DateTimeUtil.getLocalDateTime(endTime));
                loginRecord.setGmtModified(DateTimeUtil.getLocalDateTime(endTime));
                loginRecord.setDataId(YitIdHelper.nextId());
                resDevLoginRecordService.save(loginRecord);
            }

        }


    }
}
